#include "ClientRequestAnalyzer.h"

ClientRequestAnalyzer::ClientRequestAnalyzer(ClientSocketHandler *clientSocketHandler) {
    // 以\r\n为界，把请求数据拆分成单独的行，存入动态数组lines
    std::vector<std::string> lines;
    this->_requestToLines(clientSocketHandler, lines);

    // 开始解析请求数据
    this->_analyzeFirstLine(lines[0]);      // 首行
    for (int i = 1; i < lines.size(); i++) {
        this->_analyzeDataLine(lines[i]);   // 数据行
    }
}

void ClientRequestAnalyzer::_requestToLines(ClientSocketHandler *clientSocketHandler, std::vector<std::string> &lines) {
    std::string tempStr = "";
    while (1) {
        char c;
        if(false == clientSocketHandler->_getNextByte(&c)) {
            this->_analyzeSuccessed = false;// 读取失败，则同步标识解析失败
            return;
        }
        this->_analyzeSuccessed = true;     // 解析成功

        // 打印获取的请求内容（方便我们查看）
        printf("%c", c);

        tempStr += c;
        // 一个有效行读取完毕（最短长度不小于2，最后两个字符是\r\n）
        if(tempStr.length() >= 2 && tempStr[tempStr.length() - 2] == '\r' && tempStr[tempStr.length() - 1] == '\n') {
            // 空行（\r\n）
            if(2 == tempStr.length()) {
                break;
            }
            // 去除非空行末尾\r\n，并存入动态数组lines
            tempStr.erase(tempStr.length() - 2);
            lines.push_back(tempStr);
            tempStr.clear();    // 清空临时字符串
        }
    }
}

void ClientRequestAnalyzer::_analyzeFirstLine(std::string line) {
    std::vector<std::string> firstLineStrs; // 首行数据
    std::string tempStr = "";
    for (int i = 0; i < line.length(); i++)
    {
        // 跳过连续空格（自我补充）
        if(' ' == line[i] && 0 == tempStr.length()) {
            continue;
        }
        // tempStr存入非空数据后，遇到空格
        else if(' ' == line[i] && tempStr.length() > 0) {
            firstLineStrs.push_back(tempStr);
            tempStr.clear();
            continue;
        }
        tempStr += line[i];
    }
    if(tempStr.length() > 0) {
        firstLineStrs.push_back(tempStr);
        tempStr.clear();
    }
    // 理论上，动态数组firstLineStrs的前三个字符串分别是请求方法名称、路径、HTTP协议版本
    this->_requestName = firstLineStrs[0];
    this->_url = firstLineStrs[1];
    this->_httpVersion = firstLineStrs[2];
}

void ClientRequestAnalyzer::_analyzeDataLine(std::string line) {
    // eg：Host: 127.0.0.1
    _RequestKeyData keyData;
    for (int i = 0; i < line.length(); i++) {
        if(':' == line[i]) {
            keyData.Key = line.substr(0, i);    // 键
            i++;
            while (' ' == line[i]) {            // 跳过:后面的空格
                i++;
            }
        }
        keyData.Data = line.substr(i);          // 值（下标i到末尾的子串）

        // 统一把键值对中的字母都转为小写（方便查询）
        std::transform(keyData.Key.begin(), keyData.Key.end(), keyData.Key.begin(), ::tolower);
        std::transform(keyData.Data.begin(), keyData.Data.end(), keyData.Data.begin(), ::tolower);

        // 保存
        this->_keyDataMap.insert(std::pair<std::string, _RequestKeyData>(keyData.Key, keyData));
        // todo: keyData的清理工作？
    }
}

bool ClientRequestAnalyzer::_isAnalyzeSuccessed() {
    return this->_analyzeSuccessed;
}

std::string ClientRequestAnalyzer::_getRequestName() {
    return this->_requestName;
}
std::string ClientRequestAnalyzer::_getUrl() {
    return this->_url;
}
std::string ClientRequestAnalyzer::_getHttpVersion() {
    return this->_httpVersion;
}
std::string ClientRequestAnalyzer::_getDataByKey(std::string key) {
    // 先把传进来的内容转成小写
    std::transform(key.begin(), key.end(), key.begin(), ::tolower);
    // key不存在
    if(this->_keyDataMap.end() == this->_keyDataMap.find(key)) {
        PrintLine("key [%s] 不存在", key.c_str());
        return "";
    }
    // 存在key
    return this->_keyDataMap[key].Data;
}